import re
import os
import requests
from urllib.parse import urljoin

# 爬取base_url中的图片路径
def get_pic_url():
    # HTTP 请求头，这里主要设置了 User-Agent，模拟浏览器访问
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
    }
    base_url = 'https://www.magedu.com/'

    try:
        res = requests.get(base_url, headers=headers)  # 向指定的 URL (base_url) 发送 HTTP GET 请求。
        res.raise_for_status()  # 检查请求是否成功，如果状态码表示错误（4xx 客户端错误或 5xx 服务器错误），会抛出 HTTPError 异常
        data = res.text  # 获取响应内容的文本形式（解码后的字符串）；会自动根据响应头中的编码（如 UTF-8）解码响应内容

        url_list = []
        # 使用更健壮的正则表达式
        pattern = re.compile(r'<img[^>]*src=["\']([^"\']+\.(?:jpg|jpeg|png|gif|webp))["\']', re.IGNORECASE)

        for match in pattern.finditer(data):
            img_url = match.group(1)
            # 将相对URL转换为绝对URL
            full_url = urljoin(base_url, img_url)
            url_list.append(full_url)

        return list(set(url_list))  # 去重

    except Exception as e:
        print(f"获取图片URL失败: {e}")
        return []

# 保存爬取的图片到本地
def save_pic(pic_urls):
    # 检查是否存在指定的目录，如果不存在则创建它
    if not os.path.exists('html/images'):
        os.makedirs('html/images')

    #  遍历 URL 列表
    # enumerate() 是一个内置函数，遍历可迭代对象（如列表、元组、字符串）时同时获取索引位置和对应的值
    for i, url in enumerate(pic_urls):
        try:
            res = requests.get(url, stream=True) # 发起 HTTP 请求，以流式方式下载图片（避免一次性加载大文件到内存）
            res.raise_for_status()  # 如果 HTTP 请求失败（如 404、500），会抛出异常。

            # 从URL获取文件扩展名
            ext = os.path.splitext(url)[1].lower() # 将url拆分为(文件名, 扩展名)元组，取元组的第二个元素；.lower() 是 Python 字符串的内置方法，用于将字符串中的所有大写字母转换为小写字母
            # if not ext:  # 如果URL没有扩展名，尝试从Content-Type获取
            #     content_type = res.headers.get('content-type', '')
            #     if 'image/jpeg' in content_type:
            #         ext = '.jpg'
            #     elif 'image/png' in content_type:
            #         ext = '.png'
            #     else:
            #         ext = '.jpg'  # 默认

            # 生成文件名（如 html/images/0.jpg）
            file_path = f'html/images/{i}{ext}'

            with open(file_path, 'wb') as f: # # 以二进制写入模式打开文件
                for chunk in res.iter_content(1024): # # 分块读取数据（每块1024字节）
                    f.write(chunk) # 写入文件
            print(f"成功保存图片: {file_path}")

        except Exception as e:
            print(f"下载图片失败 {url}: {e}")


if __name__ == '__main__':
    pic_urls = get_pic_url()
    print(f"找到 {len(pic_urls)} 张图片")
    save_pic(pic_urls)